package ru.amse.jsynchro.kernel;

import java.util.Deque;
import java.util.List;

import ru.amse.jsynchro.fileSystem.FileSystem;

public interface IDirectoryTree {
    /**
     * creates a new node with specified data
     * @param path a relative path to the root of tree location of node
     * @return true if succeed
     */
    boolean add(Deque<String> path, NodeData data);
    /**
    * deletes a node
    * @param path a relative path to the root of tree location of node
    * @return true if succeed
    */
    boolean remove(Deque<String> path);
    
    /**
     * writes new data in an element node
     * @param path relative path to the root of tree location of node
     * @param data new data
     * @return true if succeed
     */
    boolean update(Deque<String> path, NodeData data);
    /**
     * compares two directories and generates 
     * an array of differences according to one directed synch
     * @param second a tree of destination synchronization
     * @param deletes indicates, whether elements in second folder, 
     * which are absent in first one, will be deleted
     * For example
     * @return a table of operations necessary for synchronization.
     * Resulting differences will be changes, which are necessary to be 
     * performed in the second (not first!) directory to make 
     * directories synchronized.
     */
    List<Difference> compare(IDirectoryTree second, boolean deletes);
    /**
     * @return location of tree in file system
     */
    String getPath();
    
    List<NodeData> getSubElements(String path);
    
    void setFS(FileSystem fs);
    
    FileSystem getFS();
    
    /**
     * iterates every difference if diffs and adds 
     * atomic diffs, if difference is a folder
     * @param diffs 
     * @param atomic result, must be already created
     * @param isDel type of operation: add or delete
     */
    void addAtomicDiffs(List<Difference> diffs, List<Difference> atomic, boolean isDel);
    
    /**
     * almost ({@code addAtomicDiffs(..)}, but processes
     * only one difference
     * @param d
     * @param atomic
     * @param isDel
     */
    public void addAtomicDiff(Difference d, List<Difference> atomic, boolean isDel);
    
    /**
     * iterates every node of the tree 
     * and sets it the flag of byte comparison. 
     * This flag indicates, whether byteCompare
     * method will be invoked during analysis.
     * @param set flag of byte comparison
     */
    void setCompareFileContent(boolean set);
}
